package com.usefullc.system.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.usefullc.common.exception.BizException;
import com.usefullc.common.util.BeanUtils;
import com.usefullc.system.domain.AppDevice;
import com.usefullc.system.domain.DataDict;
import com.usefullc.system.entity.Pager;
import com.usefullc.system.mapper.DataDictMapper;
import com.usefullc.system.query.BaseQuery;
import com.usefullc.system.query.DataDictQuery;
import com.usefullc.system.vo.DataDictTreeVo;
import com.usefullc.system.vo.TreeVo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author: Sampson
 * @date: 2022-04-14 08:50
 */
@Service
public class DataDictService extends AbstractBizService<DataDictMapper,DataDict,DataDictQuery> {


    @Autowired
    private SerialNumberService serialNumberService;

    @Override
    public QueryWrapper<DataDict> getQueryWrapper(DataDictQuery query) {
        QueryWrapper<DataDict> queryWrapper = super.getQueryWrapper(query);

//        if (StringUtils.isNotEmpty(query.getCodeLike())) {
//            queryWrapper.likeRight("code",query.getCodeLike());
//        }
        return queryWrapper;
    }


    public DataDict getParentByValue(String value) {
        DataDictQuery dataDictQuery = new DataDictQuery();
        dataDictQuery.setParentId(0L);
        dataDictQuery.setValue(value);
        return this.findOne(dataDictQuery);
    }

    public DataDict getCodeLikeAndValue(String codeLike, String value) {
        DataDictQuery dataDictQuery = new DataDictQuery();
        dataDictQuery.setValue(value);
        dataDictQuery.setCodeLike(codeLike);
        return this.findOne(dataDictQuery);
    }

    public List<DataDict> getChildrenByCodeLike(String codeLike) {
        DataDictQuery query = new DataDictQuery();
        query.setOrderByColumn("orderNo");
        query.setAscOrDesc("asc");
        query.setCodeLike(codeLike);
        return this.findAll(query);
    }

    public List<DataDict> getChildrenByParentId(Long parentId) {
        DataDictQuery query = new DataDictQuery();
        query.setOrderByColumn("orderNo");
        query.setAscOrDesc("asc");
        query.setParentId(parentId);
        return this.findAll(query);
    }

    public List<DataDict> getChildrenByValue(String value) {
        DataDict parentDataDict = getParentByValue(value);
        return getChildrenByParentId(parentDataDict.getId());
    }

    public Pager<DataDictTreeVo> listByPage(DataDictQuery query) {
        query.setOrderByColumn("orderNo");
        query.setAscOrDesc("asc");
        query.setParentId(0L);
        Pager<DataDict> pager = this.findByPage(query);
        List<DataDict> dataList = pager.getDataList();
        Pager<DataDictTreeVo> newPager = new Pager<>(pager);
        List<DataDictTreeVo> newDataList = new ArrayList<>();
        newPager.setDataList(newDataList);
        if (CollectionUtils.isNotEmpty(dataList)) {
            for (DataDict dataDict : dataList) {
                DataDictTreeVo dataDictTreeVo = new DataDictTreeVo();
                newDataList.add(dataDictTreeVo);
                BeanUtils.beanCopy(dataDict, dataDictTreeVo);
                List<DataDictTreeVo> children = new ArrayList<>();
                //获取子集
                List<DataDict> childDataList = getChildrenByCodeLike(dataDict.getCode());

                setChildren(childDataList,children,dataDictTreeVo);

            }
        }
        return newPager;
    }

    private void setChildren(List<DataDict> childDataList,List<DataDictTreeVo> children,DataDictTreeVo dataDictTreeVo){
        for (DataDict childDataDict : childDataList) {
            if (childDataDict.getParentId() != dataDictTreeVo.getId().longValue()) {
                continue;
            }
            DataDictTreeVo childDataDictTreeVo = new DataDictTreeVo();
            BeanUtils.beanCopy(childDataDict, childDataDictTreeVo);
            children.add(childDataDictTreeVo);

            List<DataDictTreeVo> subChildren = new ArrayList<>();
            setChildren(childDataList,subChildren,childDataDictTreeVo);
        }
        if(children.size() > 0){
            dataDictTreeVo.setChildren(children);
        }
    }

    public List<TreeVo> listTree(DataDictQuery query){
        query.setParentId(0L);
        query.setOrderByColumn("orderNo");
        query.setAscOrDesc("asc");
        List<DataDict> dataList = this.findAll(query);
        List<TreeVo> newDataList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(dataList)) {
            for (DataDict dataDict : dataList) {
                TreeVo treeVo = new TreeVo();
                newDataList.add(treeVo);
                treeVo.setTitle(dataDict.getName());
                treeVo.setValue(dataDict.getId().toString());
                treeVo.setKey(dataDict.getId().toString());
                List<TreeVo> children = new ArrayList<>();
                //获取子集
                List<DataDict> childDataList = getChildrenByCodeLike(dataDict.getCode());

                setTreeChildren(childDataList,children,treeVo);
            }
        }
        return newDataList;
    }

    private void setTreeChildren(List<DataDict> childDataList,List<TreeVo> children,TreeVo treeVo){
        for (DataDict childDataDict : childDataList) {
            if (childDataDict.getParentId() != Long.valueOf(treeVo.getValue()).longValue()) {
                continue;
            }
            TreeVo childTreeVo = new TreeVo();
            childTreeVo.setTitle(childDataDict.getName());
            childTreeVo.setValue(childDataDict.getId().toString());
            childTreeVo.setKey(childDataDict.getId().toString());
            children.add(childTreeVo);

            List<TreeVo> subChildren = new ArrayList<>();
            setTreeChildren(childDataList,subChildren,childTreeVo);
        }
        if(children.size() > 0){
            treeVo.setChildren(children);
        }
    }



    public DataDict saveDataDict(DataDict dataDict) {
        Long parentId = dataDict.getParentId();
        if (parentId == null) {
            parentId = 0L;
        }
        String parentCode = "0";
        if(parentId != 0){
            dataDict.setParentId(parentId);
            parentCode = this.findById(parentId).getCode();
        }
        dataDict.setParentId(parentId);
        String no = serialNumberService.getSerialNumber("sys_data_dict", parentCode);
        dataDict.setCode(no);
        this.save(dataDict);
        return dataDict;
    }

    public DataDict updateDataDict(DataDict dataDict){
        Long parentId = dataDict.getParentId();
        if (parentId == null) {
            parentId = 0L;
        }
        if(parentId.longValue() == dataDict.getId()){
            throw new BizException("不能作为自己的父级",false);
        }
        DataDict oldBean = this.findById(dataDict.getId());
        Long oldParentId = oldBean.getParentId();
        BeanUtils.beanCopy(dataDict,oldBean);
        if(oldParentId == parentId.longValue()){  //直接修改属性
            this.save(oldBean);
        }else{  //修改了父级，则涉及到的编码包括该级的下一级编码都得改
            String parentCode = "0";
            if(parentId != 0){
                parentCode = this.findById(parentId).getCode();
            }
            String no = serialNumberService.getSerialNumber("sys_data_dict", parentCode);
            oldBean.setCode(no);
            this.save(oldBean);

            //查询下一级修改
            updateChildrenForNo(oldBean.getId(),no);
        }
        return oldBean;
    }

    private void updateChildrenForNo(Long parentId,String parentNo){
        List<DataDict> childDataDictList = this.getChildrenByParentId(parentId);
        if(CollectionUtils.isNotEmpty(childDataDictList)){
            for (DataDict childDataDict : childDataDictList) {
                String childNo = serialNumberService.getSerialNumber("sys_data_dict", parentNo);
                childDataDict.setCode(childNo);
                this.save(childDataDict);

                updateChildrenForNo(childDataDict.getId(),childNo);

            }
        }
    }




    public int del(List<Long> ids){
        for (Long id : ids) {
            DataDict dataDict = this.findById(id);
            this.getBaseMapper().delByCodeLike(dataDict.getCode());
        }
        return 1;
    }

}
